{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "authorship_tag": "ABX9TyNeMGREkHeEkWg9fNIKrIvs",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/Maplemx/Agently/blob/main/playground/long_text_to_qa_pairs.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Long Text to Question & Answer Pairs"
      ],
      "metadata": {
        "id": "bpS4tFIa1zkV"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Demo Description\n",
        "\n",
        "**Author:** Agently Team\n",
        "\n",
        "**Prompt Language:** English\n",
        "\n",
        "**Agent Components:** None\n",
        "\n",
        "**Description:**\n",
        "\n",
        "When we try to build a vector database of our own knowledge or try to fine-tune language model, question & answer pairs are more useful than a very long piece of text.\n",
        "\n",
        "How can we generate question & answer pairs from long text and storage them in a structure data format like dictionaries in a list in an easy way? This demo shows an easy solution powered by Agently framework.\n",
        "\n",
        "当我们尝试使用向量数据库构建我们自己的知识库（比如做RAG知识增强时），或是当我们尝试微调我们的模型时，使用问答对比直接传入大块的文本更加合适。\n",
        "\n",
        "那我们应该怎样通过长文本生成相关的问答对呢？我们怎样让这些生成的问答对是结构化的，能够被存储到具有特定数据结构的变量（比如在一个list里存入大量结构一致的dict）里呢？这个案例使用Agently框架给出了一种简单的实现思路。"
      ],
      "metadata": {
        "id": "Y9vBQT5418tP"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Step 1: Install Packages"
      ],
      "metadata": {
        "id": "cGSvzpRZ23it"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install -U Agently\n",
        "!pip install requests"
      ],
      "metadata": {
        "id": "OxeTSDc_20lG"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Step 2: Demo Code\n",
        "\n",
        "> ⚠️ Directly run this demo may take a long time, consume a significant amount of tokens and cost a lot of money because this demo use [Agently README document](http://github.com/Maplemx/Agently) by default and it is a very long markdown document.\n",
        ">\n",
        "> 警告：直接启动这个DEMO会等待很长时间，并耗用大量的Token，因为它处理的目标文档是Agently的[项目介绍文档](http://github.com/Maplemx/Agently)，这是一个非常长的文档\n",
        "\n",
        "If you want to try this demo, make sure you change `document_link` to a shorter markdown document first.\n",
        "\n",
        "如果你想要尝试运行这个DEMO，请务必先行修改`document_link`，指向更短的markdown文档"
      ],
      "metadata": {
        "id": "uzG8JpJz3H-F"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import Agently\n",
        "import requests\n",
        "import time\n",
        "\n",
        "# Model Settings\n",
        "agent_factory = Agently.AgentFactory()\\\n",
        "    .set_settings(\"model.OpenAI.auth\", { \"api_key\": \"\" })\\\n",
        "    .set_settings(\"model.OpenAI.options\", { \"model\": \"gpt-3.5-turbo-16k\" })\n",
        "    # recommend using 16k or larger context model for this kind of tasks\n",
        "\n",
        "# Download document\n",
        "document_link = \"https://raw.githubusercontent.com/Maplemx/Agently/main/README.md\"\n",
        "document_content = \"\"\n",
        "response = requests.get(document_link)\n",
        "if response.status_code == 200:\n",
        "    document_content = response.content.decode(\"utf-8\")\n",
        "\n",
        "# Work Settings\n",
        "piece_length_control = 1000\n",
        "sleep_time = 5 # sleep for a while in case of reaching API request limit\n",
        "\n",
        "# Chop document\n",
        "chunks = document_content.split(\"\\n\\n\")\n",
        "paragraphs = []\n",
        "paragraph_num = -1\n",
        "for chunk in chunks:\n",
        "    if chunk.startswith(\"#\"):\n",
        "        paragraphs.append(chunk + \"\\n\\n\")\n",
        "        paragraph_num += 1\n",
        "    else:\n",
        "        paragraphs[paragraph_num] += chunk + \"\\n\\n\"\n",
        "\n",
        "text_pieces = []\n",
        "text_piece_num = 0\n",
        "for paragraph in paragraphs:\n",
        "    if len(text_pieces) == 0:\n",
        "        text_pieces.append(paragraph)\n",
        "    else:\n",
        "        if len(text_pieces[text_piece_num] + paragraph) > piece_length_control:\n",
        "            text_pieces.append(paragraph)\n",
        "            text_piece_num += 1\n",
        "        else:\n",
        "            text_pieces[text_piece_num] += paragraph\n",
        "\n",
        "# Generate QA Pairs\n",
        "qa_pairs = []\n",
        "agent = agent_factory.create_agent()\n",
        "for text_piece in text_pieces:\n",
        "    print(\"[Working on]: \", text_piece.split(\"\\n\")[0])\n",
        "    result = agent\\\n",
        "        .input({\"text\": text_piece })\\\n",
        "        .instruct(\"Generate at least 5 question and answer pairs about {text}\")\\\n",
        "        .output([{\n",
        "            \"question\": (\"String\", \"Question you may ask about {text}\"),\n",
        "            \"answer\": (\"String\", \"Your answer to {question} according {text}\"),\n",
        "        }])\\\n",
        "        .start()\n",
        "    qa_pairs.append({\n",
        "        \"origin_piece\": text_piece,\n",
        "        \"qa_pairs\": result,\n",
        "    })\n",
        "    print(\"[Done] Start next work in \" + str(sleep_time) + \" seconds.\")\n",
        "    time.sleep(sleep_time)\n",
        "print(\"[All Works Done]\\n\")\n",
        "\n",
        "# Print QA Paris\n",
        "for item in qa_pairs:\n",
        "    print(\"[Origin Text Piece]: \\n\", item[\"origin_piece\"], end=\"\\n\")\n",
        "    for qa in item[\"qa_pairs\"]:\n",
        "        print(\"Question: \", qa[\"question\"])\n",
        "        print(\"Answer: \", qa[\"answer\"], end=\"\\n\")\n",
        "    print(\"------\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3tJP8Ywy3QB1",
        "outputId": "91b26ff1-8dbc-4c9f-9e3a-14933d2c5fcc"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[Working on]:  ## **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_ 3.0 Guidebook**\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### Chat Group & Community\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  # Interact with the agent instance like calling a function\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### What is AI Agent Native Application?\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### DEMO 1: SQL Generator\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### DEMO 2: Character Creator (and Chat with the Character)\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  # Create Character\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ## Easy to Enhance and Update: Enhance AI Agent using Plugins instead of Rebuild a Whole New Agent\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### Why does **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_** care plugin-to-enhance so much?\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### Agent Structure that **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_** Framework Can Help to Build\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  # Create Plugin Class comply with Abstract Basic Class\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  # Export to Plugins Dir Auto Scaner\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ### EXAMPLE 2: Install Plugins outside the Package\n",
            "[Done] Start next work in 5 seconds.\n",
            "[Working on]:  ## Want to Dive Deeper?\n",
            "[Done] Start next work in 5 seconds.\n",
            "[All Works Done]\n",
            "\n",
            "[Origin Text Piece]: \n",
            " ## **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_ 3.0 Guidebook**\n",
            "\n",
            "> How to use: `pip install -U Agently`\n",
            ">\n",
            "> Github Repo: [https://github.com/Maplemx/Agently](https://github.com/Maplemx/Agently)\n",
            ">\n",
            "> Contact Us: [developer@agently.cn](mailto:developer@agently.cn)\n",
            ">\n",
            "> Ideas / Bug Report: [Report Issues Here](https://github.com/Maplemx/Agently/issues)\n",
            "> \n",
            "> If you like this project, please ⭐️, thanks.\n",
            "\n",
            "### Resources Menu\n",
            "\n",
            "**Colab Documents:**\n",
            "\n",
            "[[Introduction Guidebook](https://github.com/Maplemx/Agently/blob/main/docs/guidebook/introduction.ipynb)] | [[Application Development Handbook](https://github.com/Maplemx/Agently/blob/main/docs/guidebook/application_development_handbook.ipynb)] | [Plugin Development Handbook(still working on it)]\n",
            "\n",
            "**Code Examples:**\n",
            "\n",
            "[[Demostration Playground](https://github.com/Maplemx/Agently/tree/main/playground)]\n",
            "\n",
            "\n",
            "Question:  How can I install Agently?\n",
            "Answer:  You can install Agently by running 'pip install -U Agently'.\n",
            "Question:  Where can I find the Github repository for Agently?\n",
            "Answer:  You can find the Github repository for Agently at [https://github.com/Maplemx/Agently](https://github.com/Maplemx/Agently).\n",
            "Question:  How can I contact the developers of Agently?\n",
            "Answer:  You can contact the developers of Agently by sending an email to developer@agently.cn.\n",
            "Question:  Where can I report ideas or bugs related to Agently?\n",
            "Answer:  You can report ideas or bugs related to Agently at [https://github.com/Maplemx/Agently/issues](https://github.com/Maplemx/Agently/issues).\n",
            "Question:  Where can I find the Colab documents for Agently?\n",
            "Answer:  You can find the Colab documents for Agently at the following links: [Introduction Guidebook](https://github.com/Maplemx/Agently/blob/main/docs/guidebook/introduction.ipynb), [Application Development Handbook](https://github.com/Maplemx/Agently/blob/main/docs/guidebook/application_development_handbook.ipynb), and Plugin Development Handbook (still working on it).\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### Chat Group & Community\n",
            "\n",
            "👾 Discord Group: [Click Here to Join](https://discord.gg/AKPhfzzv)\n",
            "\n",
            "💬 WeChat Group: [Click Here to Apply](https://doc.weixin.qq.com/forms/AIoA8gcHAFMASAAiQZQABIeD2vLjuGQef)\n",
            "\n",
            "\n",
            "\n",
            "## Installation & Preparation\n",
            "\n",
            "Install Agently Python Package:\n",
            "\n",
            "```shell\n",
            "pip install -U Agently\n",
            "```\n",
            "\n",
            "Then we are ready to go!\n",
            "\n",
            "## What is **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_** ?\n",
            "\n",
            "Agently is a development framework that helps developers build AI agent native application really fast.\n",
            "\n",
            "You can use and build AI agent in your code in an extremely simple way.\n",
            "\n",
            "You can create an AI agent instance then interact with it like calling a function in very few codes like this below.\n",
            "\n",
            "Click the run button below and witness the magic. It's just that simple:\n",
            "\n",
            "\n",
            "```python\n",
            "# Import and Init Settings\n",
            "import Agently\n",
            "agent = Agently.create_agent()\n",
            "agent\\\n",
            "    .set_settings(\"use_model\", \"OpenAI\")\\\n",
            "    .set_settings(\"model.OpenAI.auth\", { \"api_key\": \"\" })\n",
            "\n",
            "\n",
            "Question:  What is Agently?\n",
            "Answer:  Agently is a development framework that helps developers build AI agent native applications really fast.\n",
            "Question:  How can Agently be installed?\n",
            "Answer:  Agently can be installed by running the command 'pip install -U Agently' in the shell.\n",
            "Question:  What is the purpose of the Agently Python package?\n",
            "Answer:  The purpose of the Agently Python package is to allow developers to use and build AI agent in their code in an extremely simple way.\n",
            "Question:  How can an AI agent instance be created using Agently?\n",
            "Answer:  An AI agent instance can be created by importing Agently and calling the 'create_agent' function. An example code is provided in the text.\n",
            "Question:  What does the 'set_settings' method do in Agently?\n",
            "Answer:  The 'set_settings' method in Agently is used to set specific settings for the AI agent, such as the model to be used and the authentication details for the model. An example code is provided in the text.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " # Interact with the agent instance like calling a function\n",
            "result = agent\\\n",
            "    .input(\"Give me 3 words\")\\\n",
            "    .output([(\"String\", \"one word\")])\\\n",
            "    .start()\n",
            "print(result)\n",
            "```\n",
            "\n",
            "    ['apple', 'banana', 'carrot']\n",
            "\n",
            "\n",
            "\n",
            "\n",
            "And you may notice that when we print the value of `result`, the value is a `list` just like the format of parameter we put into the `.output()`.\n",
            "\n",
            "In Agently framework we've done a lot of work like this to make it easier for application developers to integrate Agent instances into their business code. This will allow application developers to focus on how to build their business logic instead of figure out how to cater to language models or how to keep models satisfied.\n",
            "\n",
            "\n",
            "\n",
            "## Easy to Use: Develop AI Agent Native Application Module in an Incredible Easy Way\n",
            "\n",
            "\n",
            "Question:  What functionality does the 'agent' object provide?\n",
            "Answer:  The 'agent' object provides functionality to interact with the agent instance, like calling a function.\n",
            "Question:  What is the purpose of the '.input()' function?\n",
            "Answer:  The '.input()' function is used to provide input to the agent instance, in this case, the user is asked to give 3 words.\n",
            "Question:  What parameter is passed to the '.output()' function?\n",
            "Answer:  The parameter passed to the '.output()' function is a list of tuples. Each tuple contains a data type and a value, in this case, the data type is 'String' and the value is 'one word'.\n",
            "Question:  What does the 'start()' function do?\n",
            "Answer:  The 'start()' function is used to start the agent instance and get the result.\n",
            "Question:  What is the value of 'result' after calling 'start()'?\n",
            "Answer:  The value of 'result' is a list containing the words 'apple', 'banana', and 'carrot'.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### What is AI Agent Native Application?\n",
            "\n",
            "When we start using AI agent in code to help us handle business logic, we can easily sence that there must be some differences from the traditional software develop way. But what're the differences exactly?\n",
            "\n",
            "I think the key point is to use an AI agent to solve the problem instead of man-made code logic.\n",
            "\n",
            "In AI agent native application, we put an AI agent instance into our code, then we ask it to execute / to solve the problem with natural language or natural-language-like expressions.\n",
            "\n",
            "\"Ask-Get Response\" takes place of traditional \"Define Problem - Programme - Code to Make It Happen\".\n",
            "\n",
            "Can that be true and as easy as we say?\n",
            "\n",
            "Sure! Agently framework provide the easy way to interact with AI agent instance will make application module development quick and easy.\n",
            "\n",
            "Here down below are two CLI application demos that in two totally different domains but both be built by 64 lines of codes powered by Agently.\n",
            "\n",
            "\n",
            "Question:  What is an AI Agent Native Application?\n",
            "Answer:  An AI agent native application is when we put an AI agent instance into our code, and use it to execute or solve problems using natural language or natural-language-like expressions.\n",
            "Question:  What is the key difference between using an AI agent and traditional software development?\n",
            "Answer:  The key difference is that with AI agent, we use it to solve problems instead of manually coding the logic.\n",
            "Question:  What is the role of 'Ask-Get Response' in AI agent native applications?\n",
            "Answer:  'Ask-Get Response' replaces the traditional process of 'Define Problem - Programme - Code to Make It Happen' in AI agent native applications.\n",
            "Question:  How does the Agently framework help in developing AI agent native applications?\n",
            "Answer:  The Agently framework provides an easy way to interact with AI agent instances, making application module development quick and easy.\n",
            "Question:  What are the two CLI application demos mentioned in the text?\n",
            "Answer:  The text mentions two CLI application demos built using Agently, but does not specify their domains.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### DEMO 1: SQL Generator\n",
            "\n",
            "**DEMO VEDIO**\n",
            "\n",
            "https://github.com/Maplemx/Agently/assets/4413155/b7d16592-5fdc-43c0-a14c-f2272c7900da\n",
            "\n",
            "**CODE**\n",
            "\n",
            "```python\n",
            "import Agently\n",
            "agent_factory = Agently.AgentFactory(is_debug = False)\n",
            "\n",
            "agent_factory\\\n",
            "    .set_settings(\"current_model\", \"OpenAI\")\\\n",
            "    .set_settings(\"model.OpenAI.auth\", { \"api_key\": \"\" })\n",
            "\n",
            "agent = agent_factory.create_agent()\n",
            "\n",
            "meta_data = {\n",
            "    \"table_meta\" : [\n",
            "        {\n",
            "            \"table_name\": \"user\",\n",
            "            \"columns\": [\n",
            "                { \"column_name\": \"user_id\", \"desc\": \"identity of user\", \"value type\": \"Number\" },\n",
            "                { \"column_name\": \"gender\", \"desc\": \"gender of user\", \"value type\": [\"male\", \"female\"] },\n",
            "                { \"column_name\": \"age\", \"desc\": \"age of user\", \"value type\": \"Number\" },\n",
            "                { \"column_name\": \"customer_level\", \"desc\": \"level of customer account\", \"value type\": [1,2,3,4,5] },\n",
            "            ]\n",
            "        },\n",
            "        {\n",
            "            \"table_name\": \"order\",\n",
            "            \"columns\": [\n",
            "                { \"column_name\": \"order_id\", \"desc\": \"identity of order\", \"value type\": \"Number\" },\n",
            "                { \"column_name\": \"customer_user_id\", \"desc\": \"identity of customer, same value as user_id\", \"value type\": \"Number\" },\n",
            "                { \"column_name\": \"item_name\", \"desc\": \"item name of this order\", \"value type\": \"String\" },\n",
            "                { \"column_name\": \"item_number\", \"desc\": \"how many items to buy in this order\", \"value type\": \"Number\" },\n",
            "                { \"column_name\": \"price\", \"desc\": \"how much of each item\", \"value type\": \"Number\" },\n",
            "                { \"column_name\": \"date\", \"desc\": \"what date did this order happend\", \"value type\": \"Date\" },\n",
            "            ]\n",
            "        },\n",
            "    ]\n",
            "}\n",
            "\n",
            "is_finish = False\n",
            "while not is_finish:\n",
            "    question = input(\"What do you want to know: \")\n",
            "    show_thinking = None\n",
            "    while str(show_thinking).lower() not in (\"y\", \"n\"):\n",
            "        show_thinking = input(\"Do you want to observe the thinking process? [Y/N]: \")\n",
            "    show_thinking = False if show_thinking.lower == \"n\" else True\n",
            "    print(\"[Generating...]\")\n",
            "    result = agent\\\n",
            "        .input({\n",
            "            \"table_meta\": meta_data[\"table_meta\"],\n",
            "            \"question\": question\n",
            "        })\\\n",
            "        .instruct([\n",
            "            \"output SQL to query the database according meta data:{table_meta} that can anwser the question:{question}\",\n",
            "            \"output language: English\",\n",
            "        ])\\\n",
            "        .output({\n",
            "            \"thinkings\": [\"String\", \"Your problem solving thinking step by step\"],\n",
            "            \"SQL\": (\"String\", \"final SQL only\"),\n",
            "        })\\\n",
            "        .start()\n",
            "    if show_thinking:\n",
            "        thinking_process = \"\\n\".join(result[\"thinkings\"])\n",
            "        print(\"[Thinking Process]\\n\", thinking_process)\n",
            "    print(\"[SQL]\\n\", result[\"SQL\"])\n",
            "    while str(is_finish).lower() not in (\"y\", \"n\"):\n",
            "        is_finish = input(\"Do you want to quit？[Y to quit / N to continue]: \")\n",
            "    is_finish = False if is_finish.lower() == \"n\" else True\n",
            "```\n",
            "\n",
            "\n",
            "Question:  What is the purpose of this code?\n",
            "Answer:  The purpose of this code is to generate SQL queries based on the provided meta data and user input.\n",
            "Question:  What are the inputs for creating the agent?\n",
            "Answer:  The inputs for creating the agent are the current model (OpenAI) and the authentication API key.\n",
            "Question:  What is the format of the user table?\n",
            "Answer:  The user table has columns for user_id (Number), gender (male or female), age (Number), and customer_level (1,2,3,4,5).\n",
            "Question:  What is the format of the order table?\n",
            "Answer:  The order table has columns for order_id (Number), customer_user_id (Number), item_name (String), item_number (Number), price (Number), and date (Date).\n",
            "Question:  What can the agent output?\n",
            "Answer:  The agent can output the SQL query to query the database according to the provided meta data and user input, and it can also provide a thinking process of the problem-solving steps.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### DEMO 2: Character Creator (and Chat with the Character)\n",
            "\n",
            "\n",
            "```python\n",
            "import Agently\n",
            "\n",
            "agent_factory = Agently.AgentFactory(is_debug = False)\n",
            "\n",
            "agent_factory\\\n",
            "    .set_settings(\"current_model\", \"OpenAI\")\\\n",
            "    .set_settings(\"model.OpenAI.auth\", { \"api_key\": \"\" })\n",
            "\n",
            "writer_agent = agent_factory.create_agent()\n",
            "roleplay_agent = agent_factory.create_agent()\n",
            "\n",
            "\n",
            "Question:  What is the purpose of the code snippet?\n",
            "Answer:  The code snippet demonstrates how to create a character and chat with the character using the Agently library.\n",
            "Question:  What does the 'import Agently' statement do?\n",
            "Answer:  The 'import Agently' statement imports the Agently library which is used to create and manage agents.\n",
            "Question:  What is the purpose of agent_factory?\n",
            "Answer:  agent_factory is used to create instances of agent objects with specific settings and configurations.\n",
            "Question:  What model is used for the writer_agent?\n",
            "Answer:  The writer_agent uses the 'OpenAI' model.\n",
            "Question:  What is the purpose of the roleplay_agent?\n",
            "Answer:  The roleplay_agent is created as an instance of the agent_factory and can be used for role-playing scenarios with the character.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " # Create Character\n",
            "character_desc = input(\"Describe the character you want to talk to with a few words: \")\n",
            "is_accepted = \"\"\n",
            "suggestions = \"\"\n",
            "last_time_character_setting = {}\n",
            "while is_accepted.lower() != \"y\":\n",
            "    is_accepted = \"\"\n",
            "    input_dict = { \"character_desc\": character_desc }\n",
            "    if suggestions != \"\":\n",
            "        input_dict.update({ \"suggestions\": suggestions })\n",
            "        input_dict.update({ \"last_time_character_setting\": last_time_character_setting })\n",
            "    setting_result = writer_agent\\\n",
            "        .input(input_dict)\\\n",
            "        .instruct([\n",
            "            \"Design a character based on {input.character_desc}.\",\n",
            "            \"if {input.suggestions} exist, rewrite {input.last_time_character_setting} followed {input.suggestions}.\"\n",
            "          ])\\\n",
            "        .output({\n",
            "            \"name\": (\"String\",),\n",
            "            \"age\": (\"Number\",),\n",
            "            \"character\": (\"String\", \"Descriptions about the role of this character, the actions he/she likes to take, his/her behaviour habbits, etc.\"),\n",
            "            \"belief\": (\"String\", \"Belief or mottos of this character\"),\n",
            "            \"background_story\": [(\"String\", \"one part of background story of this character\")],\n",
            "            \"response_examples\": [{ \"Question\": (\"String\", \"question that user may ask this character\"), \"Response\": (\"String\", \"short and quick response that this character will say.\") }],\n",
            "        })\\\n",
            "        .on_delta(lambda data: print(data, end=\"\"))\\\n",
            "        .start()\n",
            "    while is_accepted.lower() not in (\"y\", \"n\"):\n",
            "        is_accepted = input(\"Are you satisfied with this character role setting? [Y/N]: \")\n",
            "    if is_accepted.lower() == \"n\":\n",
            "        suggestions = input(\"Do you have some suggestions about this setting? (leave this empty will redo all the setting): \")\n",
            "        if suggestions != \"\":\n",
            "            last_time_character_settings = setting_result\n",
            "print(\"[Start Loading Character Setting to Agent...]\")\n",
            "# Load Character to Agent then Chat with It\n",
            "for key, value in setting_result.items():\n",
            "    roleplay_agent.set_role(key, value)\n",
            "print(\"[Loading is Done. Let's Start Chatting](input '#exit' to quit)\")\n",
            "roleplay_agent.active_session()\n",
            "chat_input = \"\"\n",
            "while True:\n",
            "    chat_input = input(\"YOU: \")\n",
            "    if chat_input == \"#exit\":\n",
            "        break\n",
            "    print(f\"{ setting_result['name'] }: \", end=\"\")\n",
            "    roleplay_agent\\\n",
            "        .input(chat_input)\\\n",
            "        .instruct(\"Response {chat_input} follow your {ROLE} settings. Response like in a CHAT not a query or request!\")\\\n",
            "        .on_delta(lambda data: print(data, end=\"\"))\\\n",
            "        .start()\n",
            "    print(\"\")\n",
            "print(\"Bye👋~\")\n",
            "```\n",
            "\n",
            "\n",
            "Question:  What is the purpose of the 'Create Character' section?\n",
            "Answer:  The purpose of the 'Create Character' section is to design a character based on the input given by the user.\n",
            "Question:  How does the code handle character setting suggestions?\n",
            "Answer:  If the user has suggestions for the character setting, the code allows them to provide those suggestions and incorporates them into the setting.\n",
            "Question:  What are the possible attributes of the character that can be specified?\n",
            "Answer:  The possible attributes of the character that can be specified include name, age, character description, beliefs, background story, and response examples.\n",
            "Question:  What happens if the user is not satisfied with the character role setting?\n",
            "Answer:  If the user is not satisfied with the character role setting, they have the option to provide suggestions for modifications or redo the entire setting.\n",
            "Question:  How does the code load the character setting to the agent?\n",
            "Answer:  The code loads the character setting to the agent by setting the role of each attribute in the setting using the 'set_role' function.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ## Easy to Enhance and Update: Enhance AI Agent using Plugins instead of Rebuild a Whole New Agent\n",
            "\n",
            "\n",
            "\n",
            "\n",
            "Question:  What is the advantage of using plugins to enhance an AI Agent instead of rebuilding a whole new agent?\n",
            "Answer:  The advantage of using plugins is that it is easy to enhance and update the AI Agent without the need to rebuild a whole new agent.\n",
            "Question:  How does using plugins benefit in enhancing and updating an AI Agent?\n",
            "Answer:  Using plugins allows for easy enhancement and update of the AI Agent without the need for a complete rebuild.\n",
            "Question:  What does the use of plugins instead of rebuilding a whole new agent provide in terms of enhancing an AI Agent?\n",
            "Answer:  Using plugins provides a convenient way to enhance and update the AI Agent without the need to start from scratch and rebuild the entire agent.\n",
            "Question:  What is the main idea behind using plugins to enhance an AI Agent?\n",
            "Answer:  The main idea is to avoid the need for rebuilding a whole new agent by utilizing plugins for easy enhancement and update of the existing agent.\n",
            "Question:  Why is it preferable to use plugins instead of rebuilding when enhancing an AI Agent?\n",
            "Answer:  Using plugins is preferable because it allows for convenient enhancement and update of the AI Agent without the time and effort required to rebuild the whole agent.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### Why does **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_** care plugin-to-enhance so much?\n",
            "\n",
            "The post about [LLM Powered Autonomous Agents](https://lilianweng.github.io/posts/2023-06-23-agent/) by Lilian Weng from OpenAI has given a really good concept of the basic structure of AI agent. But the post did not give the explanation about how to build an AI agent.\n",
            "\n",
            "Some awesome projects like [LangChain](https://python.langchain.com/docs/modules/agents/) and [Camel-AI](https://github.com/camel-ai/camel/tree/master/camel/agents) present their ideas about how to build AI agent. In these projects, agents are classified into many different type according the task of the agent or the thinking process of the agent.\n",
            "\n",
            "But if we follow these ideas to build agents, that means we must build a whole new agent if we want to have a new agent to work in a different domain. Even though all the projects provide a ChatAgent basic class or something like that, still new agent sub-classes will be built and more and more specific types of agent will be produce. With the number of agent types increasing, one day, boom! There'll be too many types of agent for developer to choose and for agent platform to manage. They'll be hard to seach, hard to choose, hard to manage and hard to update.\n",
            "\n",
            "So Agently team can not stop wondering if there's a better way to enhance agent and make all developers easy to participate in.\n",
            "\n",
            "Also, AI agent's structure and components seems simple and easy to build at present. But if we look further ahead, each component shall be more complex (memory management for example) and more and more new components will be added in (sencors for example).\n",
            "\n",
            "What if we stop building agent like an undivded whole but to seperate it into a center structure which is managing the runtime context data and runtime process and connect wiht different plugins to enhance its abilities in the runtime process to make it suitable for different usage scene? \"Divide and conquer\", just like the famous engineering motto said.\n",
            "\n",
            "We make it happened in Agently 3.0 and when Agently 3.0 in its alpha test, we were happy to see this plugin-to-enhance design not only solved the problem about rebuild a whole new agent, but also helped each component developers focuing on the target and questions only that component care about without distraction. That makes component plugin develop really easy and code simple.\n",
            "\n",
            "\n",
            "Question:  What does the concept of AI agent's basic structure refer to?\n",
            "Answer:  The concept of AI agent's basic structure refers to the fundamental components and organization of an AI agent.\n",
            "Question:  How are agents classified in projects like LangChain and Camel-AI?\n",
            "Answer:  Agents are classified into different types based on their tasks or thinking processes in projects like LangChain and Camel-AI.\n",
            "Question:  What is the potential issue with building a whole new agent for different domains?\n",
            "Answer:  The potential issue with building a whole new agent for different domains is that as the number of agent types increases, it becomes harder to choose, manage, and update them.\n",
            "Question:  How can the use of plugins enhance the abilities of an agent?\n",
            "Answer:  The use of plugins can enhance the abilities of an agent by connecting with different plugins during the runtime process, allowing the agent to adapt to different usage scenarios.\n",
            "Question:  What advantage does the plugin-to-enhance design bring to component developers?\n",
            "Answer:  The plugin-to-enhance design allows component developers to focus on their specific target and questions without distraction, making component plugin development easy and code simple.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### Agent Structure that **_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_** Framework Can Help to Build\n",
            "\n",
            "<img width=\"883\" alt=\"image\" src=\"https://github.com/Maplemx/Agently/assets/4413155/76cb456f-7025-429c-8b5a-f60789bbacef\">\n",
            "\n",
            "### EXAMPLE 1: Source Code of Agent Component - Role\n",
            "\n",
            "Here's an example that shows how to develop an agent component plugin in Agently framework. Because of the runtime context data management work has been done by the framework, plugin developers can use many runtime tools to help building the agent component plugin. That makes the work pretty easy.\n",
            "\n",
            "> ⚠️: The code below is an plugin code example, it works in the framework and can not be run seperately.\n",
            "\n",
            "\n",
            "```python\n",
            "from .utils import ComponentABC\n",
            "from Agently.utils import RuntimeCtxNamespace\n",
            "\n",
            "\n",
            "Question:  What does Agently framework help to build?\n",
            "Answer:  Agently framework helps to build an agent structure.\n",
            "Question:  What is the purpose of the agent component plugin in Agently framework?\n",
            "Answer:  The purpose of the agent component plugin in Agently framework is to develop a plugin that can be used in the framework to manage runtime context data.\n",
            "Question:  What tools can plugin developers use in Agently framework?\n",
            "Answer:  Plugin developers can use many runtime tools to help build the agent component plugin in Agently framework.\n",
            "Question:  Can the plugin code example be run separately outside the framework?\n",
            "Answer:  No, the plugin code example cannot be run separately outside the framework.\n",
            "Question:  What is the role of the Agent Component - Role in Agently framework?\n",
            "Answer:  The Agent Component - Role is a source code example that shows how to develop an agent component plugin in Agently framework.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " # Create Plugin Class comply with Abstract Basic Class\n",
            "class Role(ComponentABC):\n",
            "    def __init__(self, agent: object):\n",
            "        self.agent = agent\n",
            "        # Framework pass runtime_ctx and storage through and component can use them\n",
            "        self.role_runtime_ctx = RuntimeCtxNamespace(\"role\", self.agent.agent_runtime_ctx)\n",
            "        self.role_storage = self.agent.global_storage.table(\"role\")\n",
            "\n",
            "    # Defined methods of this component\n",
            "    # Update runtime_ctx which follow the agent instance lifetime circle\n",
            "    def set_name(self, name: str, *, target: str):\n",
            "        self.role_runtime_ctx.set(\"NAME\", name)\n",
            "        return self.agent\n",
            "\n",
            "    def set(self, key: any, value: any=None, *, target: str):\n",
            "        if value is not None:\n",
            "            self.role_runtime_ctx.set(key, value)\n",
            "        else:\n",
            "            self.role_runtime_ctx.set(\"DESC\", key)\n",
            "        return self.agent\n",
            "\n",
            "    def update(self, key: any, value: any=None, *, target: str):\n",
            "        if value is not None:\n",
            "            self.role_runtime_ctx.update(key, value)\n",
            "        else:\n",
            "            self.role_runtime_ctx.update(\"DESC\", key)\n",
            "        return self.agent\n",
            "\n",
            "    def append(self, key: any, value: any=None, *, target: str):\n",
            "        if value is not None:\n",
            "            self.role_runtime_ctx.append(key, value)\n",
            "        else:\n",
            "            self.role_runtime_ctx.append(\"DESC\", key)\n",
            "        return self.agent\n",
            "\n",
            "    def extend(self, key: any, value: any=None, *, target: str):\n",
            "        if value is not None:\n",
            "            self.role_runtime_ctx.extend(key, value)\n",
            "        else:\n",
            "            self.role_runtime_ctx.extend(\"DESC\", key)\n",
            "        return self.agent\n",
            "\n",
            "    # Or save to / load from storage which keep the data in file storage or database\n",
            "    def save(self, role_name: str=None):\n",
            "        if role_name == None:\n",
            "            role_name = self.role_runtime_ctx.get(\"NAME\")\n",
            "        if role_name != None and role_name != \"\":\n",
            "            self.role_storage\\\n",
            "                .set(role_name, self.role_runtime_ctx.get())\\\n",
            "                .save()\n",
            "            return self.agent\n",
            "        else:\n",
            "            raise Exception(\"[Agent Component: Role] Role attr 'NAME' must be stated before save. Use .set_role_name() to specific that.\")\n",
            "\n",
            "    def load(self, role_name: str):\n",
            "        role_data = self.role_storage.get(role_name)\n",
            "        for key, value in role_data.items():\n",
            "            self.role_runtime_ctx.update(key, value)\n",
            "        return self.agent\n",
            "\n",
            "    # Pass the data to request standard slots on Prefix Stage\n",
            "    def _prefix(self):\n",
            "        return {\n",
            "            \"role\": self.role_runtime_ctx.get(),\n",
            "        }\n",
            "\n",
            "    # Export component plugin interface to be called in agent runtime process\n",
            "    def export(self):\n",
            "        return {\n",
            "            \"early\": None, # method to be called on Early Stage\n",
            "            \"prefix\": self._prefix, # method to be called on Prefix Stage\n",
            "            \"suffix\": None, # mothod to be called on Suffix Stage\n",
            "            # Alias that application developers can use in agent instance\n",
            "            # Example:\n",
            "            # \"alias\": { \"set_role_name\": { \"func\": self.set_name } }\n",
            "            # => agent.set_role_name(\"Alice\")\n",
            "            \"alias\": {\n",
            "                \"set_role_name\": { \"func\": self.set_name },\n",
            "                \"set_role\": { \"func\": self.set },\n",
            "                \"update_role\": { \"func\": self.update },\n",
            "                \"append_role\": { \"func\": self.append },\n",
            "                \"extend_role\": { \"func\": self.extend },\n",
            "                \"save_role\": { \"func\": self.save },\n",
            "                \"load_role\": { \"func\": self.load },\n",
            "            },\n",
            "        }\n",
            "\n",
            "\n",
            "Question:  What is the purpose of the Role class?\n",
            "Answer:  The purpose of the Role class is to create a plugin class that complies with the Abstract Basic Class.\n",
            "Question:  What does the 'agent' parameter in the constructor of the Role class represent?\n",
            "Answer:  The 'agent' parameter in the constructor of the Role class represents an object.\n",
            "Question:  What is the purpose of the 'role_runtime_ctx' attribute of the Role class?\n",
            "Answer:  The 'role_runtime_ctx' attribute of the Role class is used to pass the runtime context and storage through, so that the component can use them.\n",
            "Question:  What is the purpose of the 'role_storage' attribute of the Role class?\n",
            "Answer:  The 'role_storage' attribute of the Role class is used to access the global storage table named 'role'.\n",
            "Question:  What is the purpose of the 'set_name' method of the Role class?\n",
            "Answer:  The 'set_name' method of the Role class is used to set the value of the 'NAME' key in the role_runtime_ctx attribute.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " # Export to Plugins Dir Auto Scaner\n",
            "def export():\n",
            "    return (\"Role\", Role)\n",
            "```\n",
            "\n",
            "\n",
            "Question:  What is the purpose of the export() function?\n",
            "Answer:  The purpose of the export() function is to export a module named 'Role' to the Plugins Directory Auto Scanner.\n",
            "Question:  What does the export() function return?\n",
            "Answer:  The export() function returns a tuple containing the string 'Role' and the module 'Role'.\n",
            "Question:  What is the significance of the 'Role' string in the export() function?\n",
            "Answer:  The 'Role' string represents the name of the module being exported and can be used to identify the module when it is imported.\n",
            "Question:  What is the purpose of the Plugins Directory Auto Scanner?\n",
            "Answer:  The Plugins Directory Auto Scanner is responsible for automatically scanning and detecting modules in the Plugins Directory.\n",
            "Question:  What is the expected output of the export() function?\n",
            "Answer:  The expected output of the export() function is a tuple containing the string 'Role' and the module 'Role'.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ### EXAMPLE 2: Install Plugins outside the Package\n",
            "\n",
            "Agently framework also allows plugin developers pack their plugin outside the main package of framework and share their plugin package individually to other developers. Developers those who want to use a specific plugin can just download the plugin package, unpack the files into their working folder, then install the plugin easily.\n",
            "\n",
            "These codes down below will present how easy this installation can be.\n",
            "\n",
            "> ⚠️: The code below is an plugin install example, it only works when you unpack an plugin folder in your working folder.\n",
            "\n",
            "\n",
            "```python\n",
            "import Agently\n",
            "# Import install method from plugin folder\n",
            "from session_plugin import install\n",
            "# Then install\n",
            "install(Agently)\n",
            "# That's all\n",
            "# Now your agent can use new abilities enhanced by new plugin\n",
            "```\n",
            "\n",
            "Here's also [a real case](https://github.com/Maplemx/Agently/issues/32) when Agently v3.0.1 had an issue that make Session component unavailable. We use plugin package update can fix the bug without update the whole framework package.\n",
            "\n",
            "\n",
            "Question:  What is the purpose of installing plugins outside the package?\n",
            "Answer:  The purpose of installing plugins outside the package is to allow plugin developers to pack their plugins separately and share them individually with other developers.\n",
            "Question:  How can a specific plugin be installed using Agently framework?\n",
            "Answer:  To install a specific plugin using Agently framework, you can download the plugin package, unpack the files into your working folder, and then install the plugin easily.\n",
            "Question:  Can you provide an example of installing a plugin using Agently?\n",
            "Answer:  Sure! Here's an example code for installing a plugin using Agently:import Agently# Import install method from plugin folderfrom session_plugin import install# Then installinstall(Agently)# That's all# Now your agent can use new abilities enhanced by the new plugin\n",
            "Question:  How did plugin package update fix a bug in Agently?\n",
            "Answer:  In a real case where Agently v3.0.1 had an issue that made the Session component unavailable, a plugin package update was used to fix the bug without updating the whole framework package.\n",
            "Question:  Can plugins be used by downloading and unpacking the files in the working folder?\n",
            "Answer:  Yes, plugins can be used by downloading and unpacking the files into the working folder. This allows developers to easily use specific plugins without having to install the entire framework package.\n",
            "------\n",
            "[Origin Text Piece]: \n",
            " ## Want to Dive Deeper?\n",
            "\n",
            "OK. That's the general introduction about Agently AI agent development framework.\n",
            "\n",
            "If you want to dive deeper, you can also visit these documents/links:\n",
            "\n",
            "- [Agently 3.0 Application Development Handbook](https://github.com/Maplemx/Agently/blob/main/docs/guidebook/application_development_handbook.ipynb)\n",
            "- Agently 3.0 Plugin Development Handbook (Working on it)\n",
            "- [Agently 3.0 Demostration Playground](https://github.com/Maplemx/Agently/tree/main/playground)\n",
            "\n",
            "---\n",
            "\n",
            "Don't forget ⭐️ this repo if you like our work.\n",
            "\n",
            "Thanks and happy coding!\n",
            "\n",
            "\n",
            "\n",
            "Question:  What is the Agently 3.0 Application Development Handbook?\n",
            "Answer:  The Agently 3.0 Application Development Handbook is a document that provides guidance on developing applications using the Agently AI agent development framework. You can find the document [here](https://github.com/Maplemx/Agently/blob/main/docs/guidebook/application_development_handbook.ipynb).\n",
            "Question:  What is the status of the Agently 3.0 Plugin Development Handbook?\n",
            "Answer:  The Agently 3.0 Plugin Development Handbook is currently being worked on. It is a document that will provide guidance on developing plugins using the Agently AI agent development framework.\n",
            "Question:  What is the Agently 3.0 Demonstration Playground?\n",
            "Answer:  The Agently 3.0 Demonstration Playground is a repository that showcases the capabilities and features of the Agently AI agent development framework. You can find the repository [here](https://github.com/Maplemx/Agently/tree/main/playground).\n",
            "Question:  Why should I star the Agently AI repository?\n",
            "Answer:  Starring the Agently AI repository shows your appreciation for their work. It is a way to show support and recognition for the efforts put into developing the Agently AI agent development framework.\n",
            "Question:  What is the purpose of the Agently AI agent development framework?\n",
            "Answer:  The purpose of the Agently AI agent development framework is to provide a framework and guidelines for developing AI agents. It offers tools and resources to build and deploy AI agents that can perform various tasks and interact with users.\n",
            "------\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "\n",
        "\n",
        "---\n",
        "\n",
        "[**_<font color = \"red\">Agent</font><font color = \"blue\">ly</font>_** Framework - Speed up your AI Agent Native application development](https://github.com/Maplemx/Agently)"
      ],
      "metadata": {
        "id": "Imyqgd4FVHSP"
      }
    }
  ]
}